#!/bin/sh
#
# Script to configure "staticability" of plugins
# author: pancake // nopcode
# update: 2010-01-14
#

LANG=C
LC_ALL=C
LOADLIBS=1
if [ -z "$EXT_SO" ]; then
	EXT=so
	[ "`uname`" = Darwin ] && EXT=dylib
else
	EXT="${EXT_SO}"
fi

export LANG
export LC_ALL

list () {
  for a in $STATIC ; do echo "static  $a" ; done
  for a in $SHARED ; do echo "shared  $a" ; done
  exit 0
}

help () {
  echo "Usage: ./configure-plugins [options]"
  echo "  -n                   do nothing.. do not generate any file"
  echo "  --list               list all static and shared plugins"
  echo "  --rm-static [dir]    remove plugins that are already in core from dir"
  echo "  --static [name ..]   define named plugin as static"
  echo "  --shared [name ..]   define named plugin as shared"
  echo "  --help, -h           display this helpful message"
  echo "NOTE: static plugins are compiled inside the owner library"
  exit 0
}

cfg=./plugins.cfg

if [ ! -f "$cfg" ]; then
  echo "configure-plugins: Copying dist/plugins-cfg/plugins.def.cfg"
  cp -f dist/plugins-cfg/plugins.def.cfg plugins.cfg
fi

load () {
  if [ -e $cfg ]; then
    echo "configure-plugins: Loading $cfg .."
    . $cfg
  else
    echo "configure-plugins: Loading $1 .."
    . "$1"
  fi
}

save () {
  cp $cfg plugins.cfg
 # echo "STATIC=\"$STATIC\"" > $cfg
 # echo "SHARED=\"$SHARED\"" >>$cfg
}

generate_configh () {
  plugins=""
  oldlib=""
  for a in ${STATIC} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      [ -n "$oldlib" ] && echo "     0"
      oldlib=$lib
      uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      echo
      echo "#define R_${uclib}_STATIC_PLUGINS \\"
      plugins="${plugins} __${uclib}"
    fi
    echo "     &r_${lib}_plugin_${plg}, \\"
  done
  [ -n "$oldlib" ] && echo "     0"

  # CAREFULLY FILL EMPTY PLUGIN ARRAYS
  for a in ${SHARED} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      oldlib=$lib
      uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      if [ -z "`echo ${plugins} | grep __${uclib}`" ]; then
        plugins="${plugins} __${uclib}"
        echo
        echo "#define R_${uclib}_STATIC_PLUGINS 0"
      fi
    fi
  done
}

generate_asmdinc() {
  plugins=""
  oldlib=""
  for a in ${STATIC} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    echo "(SdbGperf*)&gperf_${plg},"
  done
}

generate_configmk () {
  splugins=""
  plugins=""
  oldlib=""
  for a in `echo "${STATIC} ${SHARED}" | tr " " "\n" | sort` ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      [ -n "$oldlib" ] && printf "\n"
      oldlib=$lib
      uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      printf "STATIC_${uclib}_PLUGINS="
      plugins="${plugins} __${uclib}"
    fi
    printf " p/${plg}.mk"
  done

  echo

  for a in ${SHARED} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
    if [ -z "`echo ${splugins} | grep __${uclib}`" ]; then
      splugins="${splugins} __${uclib}"
      printf "SHARED_${uclib}_TARGETS="
    fi
    printf " p/io_${plg}.${EXT}"
  done
  echo
}

generate () {
  echo "configure-plugins: Generating libr/config.h"
  cat libr/config.h.head > libr/config.h

  echo "#define R2_LOADLIBS ${LOADLIBS}" >> libr/config.h
  generate_configh >> libr/config.h
  cat libr/config.h.tail >> libr/config.h

  echo "configure-plugins: Generating libr/asm/d/config.inc"
  generate_asmdinc >> libr/asm/d/config.inc

  echo "configure-plugins: Generating libr/config.mk"
  cat libr/config.mk.head > libr/config.mk
  generate_configmk >> libr/config.mk
  cat libr/config.mk.tail >> libr/config.mk
  return
}

add () {
  for a in $1 ; do [ $a = $2 ] && return ; done ; echo $1 $2
}

sub () {
  n="" ; for a in $1 ; do [ $a = $2 ] && continue ; n="$n $a" ; done ; echo $n
}

echo | sort -t. > /dev/null 2>&1
if [ $? = 0 ]; then
  SORT="sort -t."
else
  SORT="sort"
fi

dosort () {
  ( for a in $1 ; do echo $a ; done ) | tr _ Z | ${SORT} | tr Z _
  #( for a in $1 ; do echo $a ; done ) | sort -t. --key=1,1d
}

sort_vars () {
  STATIC=$(dosort "$STATIC")
  SHARED=$(dosort "$SHARED")
}

make_static () {
  STATIC=$(add "$STATIC" $1)
  SHARED=$(sub "$SHARED" $1)
}

make_shared () {
  SHARED=$(add "$SHARED" $1)
  STATIC=$(sub "$STATIC" $1)
}

make_ () { : ; }

MODE=""
DONOTHING=0
DEFCFG=dist/plugins-cfg/plugins.def.cfg

check_conflicts () {
  CONFLICT=0
  for a in $STATIC ; do
    for b in $SHARED ; do
      if [ "$a" = "$b" ]; then
        echo "\x1b[1mError\x1b[0m: Conflict \x1b[44m$a\x1b[0m is defined as STATIC and SHARED"
        CONFLICT=1
      fi
    done
  done
  return $CONFLICT
}

rmstatic() {
  C=0
  if [ -z "$1" ]; then
    echo "Missing argument"
    exit 1
  fi
  for a in ${STATIC} ; do
    b="`echo $a | tr . _`"
    for ext in dll dylib so ; do
      f="$b.$ext"
      if [ -f "$f" ]; then
        C=$(($C+1))
	printf "  $C found\r"
        #echo "rm -f $f"
        rm -f "$f"
      fi
    done
  done
  echo "Removed $C shared plugins that are already static"
}

RMSTATIC=-

while : ; do
  [ -z "$1" ] && break
  case "$1" in
  "--static") MODE=static ; ;;
  "--shared") MODE=shared ; ;;
  "--without-gpl") DEFCFG=./plugins.nogpl.cfg ;;
  "--disable-loadlibs") LOADLIBS=0 ;;
  "--rm-static") RMSTATIC="$2" ; ;;
  "--list") sort_vars ; list ; ;;
  "-n") DONOTHING=1 ; ;;
  "-h"|"--help") help ; ;;
  *) eval make_$MODE $1 ; ;;
  esac
  shift
done

load ${DEFCFG}
sort_vars

if [ - != "${RMSTATIC}" ]; then
  if [ -z "${RMSTATIC}" ]; then
    echo "Missing argument" >&2
    exit
  fi
  if [ -d "${RMSTATIC}" ]; then
    cd "${RMSTATIC}" && rmstatic "${RMSTATIC}"
  fi
  exit 0
fi

check_conflicts || exit 1

[ ${DONOTHING} = 0 ] && generate

echo SHARED: ${SHARED}
echo STATIC: ${STATIC}

save

exit 0
